package com.ken.common.web.syslog.aop;

import com.ken.common.event.apply.utils.EventUtils;
import com.ken.common.event.constact.EventConstact;
import com.ken.common.web.syslog.annotation.SysLogInfo;
import com.ken.data.entity.syslog.SysLog;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.Date;
import java.util.Map;

@Aspect
public class SysLogAop {

    @Value("${spring.application.name}")
    private String appName;

    @Autowired
    private EventUtils eventUtils;

    /**
     * 注解添加
     */
    @Around("@annotation(com.ken.common.web.syslog.annotation.SysLogInfo)")
    public Object sysLogInsert(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {

        //获得注解
        MethodSignature signature = (MethodSignature) proceedingJoinPoint.getSignature();
        Method method = signature.getMethod();
        //获取类信息
        String className = method.getDeclaringClass().getName();
        SysLogInfo sysLogAn = method.getAnnotation(SysLogInfo.class);

        //获取请求
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        //获得请求参数
        Map<String, String[]> parameterMap = request.getParameterMap();
        //请求类型
        String methodType = request.getMethod();

        //系统日志信息
        String info = sysLogAn.value();
        //构建系统日志对象
        SysLog sysLog = new SysLog()
                .setAppName(appName)//应用名称
                .setClassName(className)//类名称
                .setMethod(method.getName())//方法名称
                .setCreateTime(new Date())//执行时间
                .setUsername(null)//操作者
                .setParams(parameterMap)//相关参数
                .setRequestType(methodType)//请求类型
                .setRequestInfo(info);//接口相关描述



        //运行目标方法
        Throwable t = null;
        Object result = null;
        try {
            result = proceedingJoinPoint.proceed();
        } catch (Throwable e) {
            //记录异常
            t = e;
            //异常继续上抛
            throw e;
        } finally {
            //设置返回类型
            sysLog.setResult(result != null ? result.getClass().getName() : null);
            //设置异常信息
            sysLog.setException(t != null ? t.getLocalizedMessage() : null);
            //发送消息
            eventUtils.sendMsg(EventConstact.SYS_LOG_MSG, sysLog, false);
        }

        return result;
    }

}
